﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Avno1Spider.Model;
using DotnetSpider.HtmlAgilityPack;

namespace Avno1Spider
{
    public class AvNewsListSpider
    {
        public int PageIndex { get; set; }
        private  readonly string dir = AppContext.BaseDirectory + Path.DirectorySeparatorChar;
        public AvNewsListSpider(int page)
        {
            PageIndex = page;
        }

        public void StartRun()
        {

            var starttask = TaskGetHtml(@"http://www.playno1.com/portal.php?mod=list&catid=78&page=" + PageIndex);
            starttask.Start();
            var html = starttask.Result;
            //Console.WriteLine(html);
            HtmlDocument document = new HtmlDocument();
            document.LoadHtml(html);
            var avnews = document.DocumentNode.SelectNodes(@"//*[@class='fire_float']");
            List<AvInfo> avInfos=new List<AvInfo>( );
            BaseRepository<AvInfo> aRepository=new  BaseRepository<AvInfo>();
            List<Task> tasks = new List<Task>();
            
            foreach (var avnew in avnews)
            {
                AvInfo avInfo = new AvInfo();

                avInfo.contenturl = avnew.SelectNodes(".//a").First().GetAttributeValue("href", string.Empty);
                if (!aRepository.IsExist(n => n.contenturl == avInfo.contenturl))
                {
                  Task t=new Task(() =>
                  {
                      avInfo.title = avnew.SelectNodes(".//img").First().GetAttributeValue("alt", string.Empty);
                      avInfo.imgsrcremote = avnew.SelectNodes(".//img").First().GetAttributeValue("src", string.Empty);



                      var saveimagetask = TaskSaveImage(avInfo.imgsrcremote,
                          avInfo.contenturl.ToLower().Replace(".html", string.Empty));
                      saveimagetask.Start();
                      avInfo.publishtime =
                          DateTime.Parse(avnew.SelectNodes(@".//*[@class='fire_left']").First().InnerText);
                      avInfo.imgsrclocal = saveimagetask.Result;
                      var getdetailtask = TaskGetHtml("http://www.playno1.com/" + avInfo.contenturl);
                      getdetailtask.Start();
                      var detailhtml = getdetailtask.Result;
                      if (!String.IsNullOrEmpty(detailhtml))
                      {
                          HtmlDocument htmlDocument = new HtmlDocument();
                          htmlDocument.LoadHtml(detailhtml);
                          var contentnode = htmlDocument.DocumentNode.SelectNodes(@".//*[@id='ct']/div[1]").First();
                          var contenthtml = contentnode.InnerHtml.ToLower();
                          var images = htmlDocument.DocumentNode.SelectNodes(@".//img");
                          foreach (var img in images)
                          {
                              var imgfilename = Guid.NewGuid().ToString("N");
                              var imgurl = img.GetAttributeValue("src", string.Empty).ToLower();

                              var saveimgtask = TaskSaveImage(imgurl, imgfilename);
                              Console.WriteLine("下载图片 URL:" + imgurl);
                              saveimgtask.Start();
                              
                              imgfilename = saveimgtask.Result;
                              Console.WriteLine("下载图片完毕!");
                              var replacetask = TaskReplaceHTML(contenthtml, imgurl, "../../" + imgfilename.ToLower());
                              replacetask.Start();
                              contenthtml = replacetask.Result;
                              Encoding code = Encoding.GetEncoding("utf-8");


                          }
                          if (!Directory.Exists(dir + "html"))
                          {
                              Directory.CreateDirectory(dir + "html");
                          }
                          if (!Directory.Exists(dir + "html"+Path.DirectorySeparatorChar+ avInfo.publishtime.Value.Date.ToString("s")))
                          {
                              Directory.CreateDirectory(dir + "html"+Path.DirectorySeparatorChar+ avInfo.publishtime.Value.Date.ToString("s"));
                          }
                          Console.WriteLine("开始保存HTML:"+ avInfo.title);
                          FileStream fs = new FileStream(
                              dir + Path.DirectorySeparatorChar + "html" + Path.DirectorySeparatorChar+ avInfo.publishtime.Value.Date.ToString("s")+Path.DirectorySeparatorChar + avInfo.publishtime.Value.Date.ToString("s")+"_"+avInfo.title.Substring(0,10) +
                              ".html", FileMode.Create, FileAccess.Write);
                          contenthtml = @"<meta http-equiv='Content - Type' content='text / html; charset = utf - 8'>" +
                                        contenthtml;
                          var data = System.Text.Encoding.UTF8.GetBytes(contenthtml);
                          fs.Write(data, 0, data.Length);

                          fs.Flush();

                          fs.Dispose();
                          Console.WriteLine("保存成功！");
                          avInfo.content = contenthtml;
                          aRepository.Add(avInfo);
                      }
                  });
                    t.Start();
                    Console.WriteLine("ID为"+t.Id+"开始运行！");

                }
                if (tasks.Count > 0)
                {
                    var isallcomplete = false;
                    var completecount = 0;
                    while (!isallcomplete)
                    {

                        foreach (var task in tasks)
                        {
                          
                            if (completecount == tasks.Count)
                            {
                                isallcomplete = true;
                                break;

                            }
                            if (task.IsCompleted)
                            {
                                completecount++;
                                Console.WriteLine("ID" + task.Id + "已完成!!");

                            }
                        }
                    }
                }
                Console.ReadKey();
            }


        }

        private Task<string> TaskReplaceHTML(string html, string oldvalue, string newvalue)
        {
            return new Task<string>(()=>html.Replace(oldvalue,newvalue));
        }
        
   
        public Task<string> TaskGetHtml(string URL)
        {
            return  new Task<string>(()=>GetHtml(URL));
        }

        private Task<WebResponse> TaskGetImg(string url)
        {
            return new Task<WebResponse>(() => GetImg(url));
        }
        private WebResponse GetImg(string url)
        {
            try
            {
                var request = (HttpWebRequest)WebRequest.Create(url);
                return request.GetResponseAsync().Result;
            }
            catch (Exception e)
            {
                return null;
            }
         
        }
        private string GetHtml(string URL)
        {
            
            Encoding encoding = new UTF8Encoding();
            HttpClientHandler handler = new HttpClientHandler();
            handler.CookieContainer.Add(new Uri("http://www.playno1.com"), new Cookie("playno1", "playno1Cookie"));
            HttpClient client = new HttpClient(handler);
            client.DefaultRequestHeaders.Add("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            client.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36");
            
            var content = client.GetByteArrayAsync(URL);
            
            var html = encoding.GetString(content.Result);
            
            return html;
        }
        private Task<string> GetDetail(string URL)
        {
            return new Task<string>(() =>GetAvInfoDetail(URL));
        }

        private string GetAvInfoDetail(string URL)
        {
            return string.Empty;
        }

        private Task<string> TaskSaveImage(string ImgURL, string fname)
        {
            return new Task<string>(()=>SaveImage(ImgURL,fname));
        }
       
        private string SaveImage(string ImgURL,string fname)
        {
            if (!Directory.Exists(dir+"img"))
            {
                Directory.CreateDirectory(dir+"img");
            }
            if (!ImgURL.StartsWith("http"))
            {
                ImgURL = "http://www.playno1.com/" + ImgURL;

            }

            var filename = dir + "img"+Path.DirectorySeparatorChar + fname + ".jpg";
            if (File.Exists(filename))
            {
                return filename;
            }
            
          
           
            try
            {

                var response = TaskGetImg(ImgURL);
                response.Start();
                var imgresponse = response.Result;
                if (imgresponse == null)
                {
                    return string.Empty;
                }
                SaveBinaryFile(imgresponse, filename);
              

            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return string.Empty;
            }
           
            return "img" + Path.DirectorySeparatorChar + fname + ".jpg";
        }
        
        private void SaveBinaryFile(WebResponse response, string fileName)
        {
            var Value = true;
            var buffer = new byte[1024];

            try
            {


                Stream outStream = File.Create(fileName);
                var inStream = response.GetResponseStream();

                int l;
                do
                {
                    l = inStream.Read(buffer, 0, buffer.Length);
                    if (l > 0)
                        outStream.Write(buffer, 0, l);
                } while (l > 0);

                inStream.Dispose();

                outStream.Dispose();

            }
            catch
            {

            }

        }

        public static int GetTotalPage()
        {
            return 0;
        }
    }
}
